From b4ce9633ac0f2e7171d005f946c525733d207e6e Mon Sep 17 00:00:00 2001 From: Jimi Xenidis Date: Sun, 3 Jun 2007 10:39:31 -0400 Subject: [PATCH] [POWERPC][FIRMWARE] Firmware can now provide an RTAS stub If the firmwares devtree contains a /rtas node, then firmware will supply the interfaces that will allow a small RTAS stub to be instantiated. The RTAS stub is simply an hvcall that passes the RTAS command block to the hypervisor. Signed-off-by: Jimi Xenidis --- xen/arch/powerpc/of_handler/Makefile | 1 + xen/arch/powerpc/of_handler/ofh.c | 1 + xen/arch/powerpc/of_handler/rtas.c | 82 ++++++++++++++++++++ xen/arch/powerpc/of_handler/vdevice.c | 2 +- xen/arch/powerpc/of_handler/xen_hvcall.S | 26 +++++-- xen/arch/powerpc/powerpc64/hypercall_table.S | 2 +- 6 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 xen/arch/powerpc/of_handler/rtas.c diff --git a/xen/arch/powerpc/of_handler/Makefile b/xen/arch/powerpc/of_handler/Makefile index 3b2dfdbe10..1f3abfa2c1 100644 --- a/xen/arch/powerpc/of_handler/Makefile +++ b/xen/arch/powerpc/of_handler/Makefile @@ -16,6 +16,7 @@ obj-y += leap.o obj-y += memory.o obj-y += ofh.o obj-y += papr.o +obj-y += rtas.o obj-y += services.o obj-y += vdevice.o obj-y += xencomm.o diff --git a/xen/arch/powerpc/of_handler/ofh.c b/xen/arch/powerpc/of_handler/ofh.c index 49febbb5e9..84ea27fb4f 100644 --- a/xen/arch/powerpc/of_handler/ofh.c +++ b/xen/arch/powerpc/of_handler/ofh.c @@ -234,6 +234,7 @@ ofh_init(ulong b) ofh_service_init(b); ofh_chosen_init(b); + ofh_rtas_init(b); ofh_options_init(b); } diff --git a/xen/arch/powerpc/of_handler/rtas.c b/xen/arch/powerpc/of_handler/rtas.c new file mode 100644 index 0000000000..4343d3c910 --- /dev/null +++ b/xen/arch/powerpc/of_handler/rtas.c @@ -0,0 +1,82 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright (C) IBM Corp. 2007 + * + * Authors: Jimi Xenidis + */ + +#include "ofh.h" +#include +#include +extern char _rtas_image_start[]; +extern char _rtas_image_end[]; + +static int +rtas_instantiate_rtas(u32 nargs, u32 nrets, s32 argp[], s32 retp[], ulong b) +{ + if (nargs == 1) { + if (nrets == 1) { + void *rtas_base_address = (void *)(ulong)argp[0]; + u32 sz = (_rtas_image_end - _rtas_image_start); + + memcpy(rtas_base_address, + DRELA(&_rtas_image_start[0], b), sz); + retp[0] = (ulong)rtas_base_address; + + return OF_SUCCESS; + } + } + return OF_FAILURE; +} + + +static struct ofh_methods _rtas_methods[] = { + { "instantiate-rtas", rtas_instantiate_rtas }, + { NULL, NULL}, +}; + +static struct ofh_ihandle _ih_rtas = { + .ofi_methods = _rtas_methods, +}; + +static int rtas_open(u32 b) +{ + u32 ih = DRELA((u32)&_ih_rtas, b); + + return ih; +} + +void ofh_rtas_init(ulong b) +{ + static const char path[] = "/rtas"; + ofdn_t n; + void *m = ofd_mem(b); + u32 sz; + + n = ofd_node_find(m, DRELA(&path[0], b)); + if (n <= 0) + return; + + sz = (_rtas_image_end - _rtas_image_start); + /* Round size up to a multiple of 0x1000 */ + sz = ALIGN_UP(sz, PAGE_SIZE); + + ofd_prop_add(m, n, DRELA((const char *)"rtas-size", b), + &sz, sizeof(sz)); + + /* create an IO node */ + ofd_io_create(m, n, (ulong)rtas_open); +} diff --git a/xen/arch/powerpc/of_handler/vdevice.c b/xen/arch/powerpc/of_handler/vdevice.c index 5ad5999cbf..8b71014072 100644 --- a/xen/arch/powerpc/of_handler/vdevice.c +++ b/xen/arch/powerpc/of_handler/vdevice.c @@ -36,7 +36,7 @@ ofh_vty_init(ofdn_t chosen, ulong b) /* find the vty */ n = ofd_node_find(mem, - DRELA((const char *)"/vdevice/vty", b)); + DRELA((const char *)"/vdevice/vty", b)); if (n > 0) { /* PAPR VTERM */ ret = ofd_getprop(mem, n, DRELA((const char *)"reg", b), diff --git a/xen/arch/powerpc/of_handler/xen_hvcall.S b/xen/arch/powerpc/of_handler/xen_hvcall.S index 0182f83c7a..2d0a15acc9 100644 --- a/xen/arch/powerpc/of_handler/xen_hvcall.S +++ b/xen/arch/powerpc/of_handler/xen_hvcall.S @@ -1,19 +1,21 @@ /* - * Copyright (C) 2005 Jimi Xenidis , IBM Corporation - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright (C) IBM Corp. 2005, 2007 + * + * Authors: Jimi Xenidis */ #include @@ -26,3 +28,17 @@ _GLOBAL(xen_hvcall) HSC blr + +/* The following stub will get instantiated as RTAS in the guest */ +#define H_RTAS_PROXY 23 + .p2align 3 + .global _rtas_image_start + .global _rtas_image_end +_rtas_image_start: + mr r4,r3 + lis r3,0xffff + ori r3,r3,H_RTAS_PROXY + HSC + blr + nop +_rtas_image_end: diff --git a/xen/arch/powerpc/powerpc64/hypercall_table.S b/xen/arch/powerpc/powerpc64/hypercall_table.S index a54c838db0..090b9592ef 100644 --- a/xen/arch/powerpc/powerpc64/hypercall_table.S +++ b/xen/arch/powerpc/powerpc64/hypercall_table.S @@ -27,7 +27,7 @@ __hypercall_table: .quad do_grant_table_op /* 20 */ .quad do_vm_assist .quad 0 /* do_update_va_mapping_otherdomain */ - .quad 0 /* do_switch_vm86 */ + .quad do_rtas_proxy /* do_switch_vm86 */ .quad do_vcpu_op .quad do_ni_hypercall /* 25 */ .quad 0 /* do_mmuext_op */ -- 2.30.2